/**
 * Object Script Start
 */
/**
 * point object
 */
//function pointObj ( posX, posY ){

var pointObj = function( posX, posY ){
	this.geoType='pointer';
	this.posX=posX;
	this.posY=posY;
	this.toString = function(){
		return '{' + posX + ', ' + posY + '}';
	};
};


/**
 * line object
 */
//function lineObj( posStart, posEnd ){
var lineObj = function( posStart, posEnd ){
	this.geoType='line';
	this.posStart = posStart;
	this.posEnd = posEnd;

	this.toString = function(){
		return this.geoType + '[' + this.posStart + ',' + this.posEnd + ']';
	}
};
/**
 * shape object
 */
//function shapeObj( iniitPointLimit ){
var multiLineObj = function( pPointLimit ){
	this.geoType='multiLine';
	this.pointList = new Array();
	this.lineList = new Array();
	this.shapeLineObj = null;
	this.pointIdx = 0;
	this.lineIdx = 0;
	this.pointLimit = 30;
	this.lineColor = '#0000FF';
	if(
		   pPointLimit != null 
		&& ( pPointLimit * 0 ) == 0
	){
		this.pointLimit = pPointLimit;
	}
	
	/**
	 * add point
	 */
	this.addPoint = function( pPoint ){
		this.pointList.push( pPoint );
		if( this.pointList.length > 1 ){
			this.shapeLineObj = new lineObj( 
				  this.pointList[ this.pointList.length - 2 ]
				, this.pointList[ this.pointList.length - 1 ]
			);
			this.lineList.push( this.shapeLineObj );
		}
		if( this.pointList.length > this.pointLimit ){
			this.shiftPoint();
		}
	};
	
	this.shiftPoint = function(){
		this.pointList.shift();
		this.lineList.shift();
	};
	
	this.hasNextPoint = function(){
		var rtVal = false;
		rtVal = this.pointIdx < this.pointList.length;
		return rtVal;
	};

	this.nextPoint = function(){
		var rtVal = null;
		if( this.hasNextPoint() ){
			rtVal = this.pointList[ this.pointIdx ];
			this.pointIdx++;
		}
		return rtVal;
	};
	
	this.getLineSize = function(){
		return this.lineList.length;
	};
	
	this.hasNextLine = function(){
		var rtVal = false;
		rtVal = this.lineIdx < this.lineList.length;
		return rtVal;
	};

	this.nextLine = function(){
		var rtVal = null;
		if( this.hasNextLine() ){
			rtVal = this.lineList[ this.lineIdx ];
			this.lineIdx++;
		}
		return rtVal;
	};
	
	this.reset = function(){
		this.pointIdx = 0;
		this.lineIdx = 0;
	};

	this.clear = function(){
		this.pointList = new Array();
		this.lineList = new Array();
		this.shapeLineObj = null;
		reset();
	};
	
	this.toString = function(){
		return this.geoType + '[' + this.pointList + ']';
	};
	
};

/**
 * shape object
 */
//function shapeObj( iniitPointLimit ){
var shapeObj = function( pPointLimit ){
	this.geoType='shape';

	this.pointList = new Array();
	this.lineList = new Array();
	this.shapeLineObj = null;
	this.pointIdx = 0;
	this.lineIdx = 0;
	this.pointLimit = 30;
	this.lineColor = '#FF0000';
	this.fillColor = '#00FF00';
	if(
		   pPointLimit != null 
		&& ( pPointLimit * 0 ) == 0
	){
		this.pointLimit = pPointLimit;
	}

	this.hasNextPoint = function(){
		var rtVal = false;
		rtVal = this.pointIdx < this.pointList.length;
		return rtVal;
	};

	this.nextPoint = function(){
		var rtVal = null;
		if( this.hasNextPoint() ){
			rtVal = this.pointList[ this.pointIdx ];
			this.pointIdx++;
		}
		return rtVal;
	};
	
	this.getLineSize = function(){
		return this.lineList.length;
	};
	
	this.hasNextLine = function(){
		var rtVal = false;
		rtVal = this.lineIdx < this.lineList.length;
		return rtVal;
	};

	this.nextLine = function(){
		var rtVal = null;
		if( this.hasNextLine() ){
			rtVal = this.lineList[ this.lineIdx ];
			this.lineIdx++;
		}
		return rtVal;
	};
	
	this.reset = function(){
		this.pointIdx = 0;
		this.lineIdx = 0;
	};

	this.clear = function(){
		this.pointList = new Array();
		this.lineList = new Array();
		this.shapeLineObj = null;
		reset();
	};

	/**
	 * add point
	 */
	this.addPoint = function( pPoint ){
		this.pointList.push( pPoint );
		if( this.pointList.length > 1 ){
			if(this.lineList.length > 1){
				this.lineList.pop();
			}
			this.shapeLineObj = new lineObj( 
				  this.pointList[ this.pointList.length - 2 ]
				, this.pointList[ this.pointList.length - 1 ]
			);
			this.lineList.push( this.shapeLineObj );
			if( this.pointList.length > 2 ){
				this.shapeLineObj = new lineObj( 
					  this.pointList[ this.pointList.length - 1 ]
					, this.pointList[ 0 ]
				);
				this.lineList.push( this.shapeLineObj );
			}
		}
		if( this.pointList.length > this.pointLimit ){
			this.shiftPoint();
		}
	};
	
	this.shiftPoint = function(){
		this.pointList.shift();
		this.lineList.shift();
		this.lineList.pop();
		if( this.pointList.length > 2 ){
			this.shapeLineObj = new lineObj( 
				  this.pointList[ this.pointList.length - 1 ]
				, this.pointList[ 0 ]
			);
			this.lineList.push( this.shapeLineObj );
		}
	};
	
	this.getArea = function(){
		
		var rtnValue = new shapeObj();
		
		var startPoint = null;
		var endPoint = null;
		var minX = 0;
		var maxX = 0;
		var minY = 0;
		var maxY = 0;
		var curPoint = null;
		
		for( cpi = 0; cpi < this.pointList.length; cpi++ ){
			curPoint = this.pointList[ cpi ];
			minX = Math.min( curPoint.posX, minX );
			maxX = Math.max( curPoint.posX, maxX );
			minY = Math.min( curPoint.posY, minY );
			maxY = Math.max( curPoint.posY, maxY );
		}
		
		startPoint = new pointObj( minX, minY );
		endPoint   = new pointObj( maxX, maxY );
		
		rtnValue.addPoint( startPoint );
		rtnValue.addPoint( endPoint );
		
		return rtnValue;
		
	};
	
	/*
	this.calculateArea = function( eventPoint, startPoint, endPoint ){
		var rtnVal = (
			  (eventPoint.posX - endPoint.posX) * (startPoint.posY - endPoint.posY) 
			- (startPoint.posX - endPoint.posX) * (eventPoint.posY - endPoint.posY)
		);
		return rtnVal;
	};
	*/
	
	this.isInShape = function( eventPos ){
		var rtnValue = false;
		var areaLineObj;
		var pointStart;
		var pointEnd;
		
		var calResult;
		var valFlag;
		
		this.reset();
		if( this.hasNextLine() ){
			rtnValue = true;
			areaLineObj = this.nextLine();
			pointStart = areaLineObj.posStart;
			pointEnd = areaLineObj.posEnd;
			//calResult = calculateArea( eventPos, pointStart, pointEnd );
			calResult = (
				  (eventPos.posX   - pointEnd.posX) * (pointStart.posY - pointEnd.posY) 
				- (pointStart.posX - pointEnd.posX) * (eventPos.posY   - pointEnd.posY)
			);
			valFlag = ( calResult < 0 );
			while( ( areaLineObj = this.nextLine() ) != null ){
				pointStart = areaLineObj.posStart;
				pointEnd = areaLineObj.posEnd;
				//calResult = calculateArea( eventPos, pointStart, pointEnd );
				calResult = (
					  (eventPos.posX   - pointEnd.posX) * (pointStart.posY - pointEnd.posY) 
					- (pointStart.posX - pointEnd.posX) * (eventPos.posY   - pointEnd.posY)
				);
				if( valFlag != ( calResult < 0 ) ){
					rtnValue = false;
					break;
				}
			}
		}
		/*
		debug( 
			  'isArea'
			+ '[' + rtnValue + ']'
			+ '[' + eventPos + ']'
			+ '[' + this + ']'
		);
		*/
		
		return rtnValue;
	};
	
	this.toString = function(){
		return 'shape[' + this.pointList + ']';
	};
	
};

